package com.hb.G_协程.A_协程基础

import kotlinx.coroutines.*

/**
 * 协程的实际使用还有一些需要改进的地方。 当我们使用 GlobalScope.launch 时，
 * 我们会创建一个顶层协程。虽然它很轻量，但它运行时仍会消耗一些内存资源。
 * 如果我们忘记保持对新启动的协程的引用，它还会继续运行。如果协程中的代码挂起了会怎么样（例如，我们错误地延迟了太长时间），
 * 如果我们启动了太多的协程并导致内存不足会怎么样？ 必须手动保持对所有已启动协程的引用并 join 之很容易出错。有一个更好的解决办法。
 * 我们可以在代码中使用结构化并发。 我们可以在执行操作所在的指定作用域内启动协程， 而不是像通常使用线程（线程总是全局的）那样在 GlobalScope 中启动。
 * 在我们的示例中，我们使用 runBlocking 协程构建器将 main 函数转换为协程。
 * 包括 runBlocking 在内的每个协程构建器都将 CoroutineScope 的实例添加到其代码块所在的作用域中。
 * 我们可以在这个作用域中启动协程而无需显式 join 之，因为外部协程（示例中的 runBlocking）直到在其作用域中启动的所有协程都执行完毕后才会结束。
 * 因此，可以将我们的示例简化为：
 */
fun main() = runBlocking { // this: CoroutineScope
    println(this)//BlockingCoroutine{Active}@bebdb06 this就是协程构建器对象，launch前面就是省略了这个
    println(this.coroutineContext)
    /*this.*/launch { // 在 runBlocking 作用域中启动一个新协程
        delay(1000L)
        println("World!")
    }
    println("Hello,")  //Hello,会等待World!执行完
    /**
     * 原因：
     * 每一个协程构建器（包括runBlocking）都会向其代码块作用域中添加一个CoroutineScope实例，我们可以在该作用域中启动协程，
     * 而无需显式将其join到一起，这是因为外部协程（在下面的事例中就是runBlocking）会等待该作用域中的所有启动的协程完成后才会完成。
     * 所以输出 " Hello,"之后会等待 "World!"执行完
     */

    /**
     * Hello,
     * World!
     *
     * 因为每个协程构建器都会将CoroutineScope这样的实例添加到他的代码块中，这是隐式添加的。
     * 这样的会我们就可以在那个范围启动协程，而不需要显示的去一起用 GlobalScope.launch。。。
     * 因为外部的协程会指导其内部的协程完成之后，外部的协程才会完成。
     */
}